/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huawei.housekeeper.service;

import com.huawei.housekeeper.exception.Assert;
import com.huawei.housekeeper.utils.JwtTokenUtil;
import com.huawei.housekeeper.enums.ErrorCode;

import lombok.extern.log4j.Log4j2;
import reactor.core.publisher.Mono;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.util.List;

/**
 * 权限校验服务
 *
 * @author y00464350
 * @since 2022-03-29
 */
@Component
@Order(11)
@Log4j2
public class AuthCheckService implements ReactiveAuthorizationManager<AuthorizationContext> {
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    public Mono<AuthorizationDecision> check(Mono<Authentication> authenticationMono, AuthorizationContext object) {
        ServerWebExchange exchange = object.getExchange();
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        // token校验
        List<String> list = headers.get(HttpHeaders.AUTHORIZATION);

        Assert.notEmpty(list, ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMessage());
        String head = list.get(0);

        Assert.isTrue(head.startsWith(tokenHead), ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMessage());
        jwtTokenUtil.isTokenExpired(head.substring(tokenHead.length()));

        String tenantDomain = request.getHeaders().get("Referer").get(0).substring(7).split("\\.")[0];
        System.out.println(tenantDomain);
        Assert.isTrue(tenantDomain.equals(jwtTokenUtil.getSchemaFromToken(head.substring(tokenHead.length()))), ErrorCode.TOKEN_ERROR.getCode(), ErrorCode.TOKEN_ERROR.getMessage());

        log.info("URL : " + request.getPath() + " ,method = " + request.getMethod());
        return Mono.just(new AuthorizationDecision(true));
    }
}